The present disclosure relates generally to the field of computer graphics. The present disclosure relates more specifically to rendering computer graphics for an electronic display.
Before an image can be rendered by a computer graphics system, it is first modeled in a format that the computer can utilize. Modeling techniques and tools describe a virtual environment with primitives that can be rendered by the graphics hardware. Primitives are basic geometric shapes such as points, lines, or polygons, and so forth. These primitives can be stretched and rotated into any position, thus allowing the construction of complex forms.
Regardless of the method used to model the virtual environment, the graphics hardware (or software) converts the modeled primitives into an array of frame buffer pixels that can be drawn on a display device. This process of converting modeled primitives into visible pixels is known as rendering.
A part of the rendering process is known as hidden surface removal (or visual priority resolution). Hidden surface removal determines which primitives in the scene should be visible for any given pixel (or sub-pixel if anti-aliasing techniques are employed). Common hidden-surface-removal techniques include the painter's algorithm, list-priority algorithms, scan line algorithms, and Z buffering, which is also known as depth buffering.
Each of the hidden-surface removal techniques has distinct advantages and disadvantages. For various reasons, the depth buffer has now become a popular choice. Most of the other approaches require special modeling techniques and support structures in order to render the image properly. The depth buffer approach eliminates many of these constraints, thereby simplifying the modeling process. With a depth buffer, the visible surface at each pixel (or sub-pixel) is simply the primitive with the closest depth value for each pixel. Depth is defined as the distance from the viewpoint to the primitive. As each primitive is rendered, this depth parameter is computed for each pixel touched by the primitive. Along with storing the color of each pixel, a frame buffer can be expanded to also store the depth value. As each new primitive is processed, the new depth is compared with the one already in the frame buffer. The frame buffer then simply keeps whichever primitive is closest to the observer.
The depth buffer technique tends to break down for primitives that are coincident with each other. A primitive is considered to be coincident if it has substantially the same depth as another primitive, such as a stripe on a road or a door on a side of a building. Limited computing precision when specifying the position of primitives relative to one another makes it mathematically difficult to consistently compute which surface is on top based on depth alone. Various techniques have been developed to assist the depth buffer to correctly select which primitive is closer to the view point. These techniques include depth value scale/offset, reference planes, stencil buffer, etc. Each of these techniques complicates the basic depth buffer algorithm in some way. Most place restrictions on the rendering process such as handling the primitives in a specific order (fix-listing) or requiring additional information to accompany the primitives.
The basic depth buffer consists of a simple comparison between an incoming pixel's depth value and the value already stored in the depth buffer. The incoming pixel's address within the 2-dimensional array of pixels stored in the frame buffer is used to select which depth is compared with the incoming depth.
Since this simple test of comparing depth values cannot consistently resolve the visual priority of coincident primitives, various techniques have been developed to augment this simple test. Each of these techniques is based on two assumptions. First, the assumption that the modeler must specify the correct visual priority order of coincident primitives. Since the order cannot be computed, it must be defined. Second, the rendering process must correctly interpret and enforce that defined order.
The simplest method adjusts the primitive's depth value such that it is forced in front or behind another primitive based on its modeled priority. This adjustment is usually a simple scale or offset of the depth value to exaggerate its position. This technique, however, is not very consistent. Adjustment values that work correctly for some primitives in the scene may not adjust other primitives far enough to be correctly resolved. In addition, other primitives in the scene may be moved too far and move in front of scene elements they are supposed to be behind.
Stencil buffering is a technique that provides a second value besides depth that can be independently stored and tested in conjunction with the depth test. A stencil value is assigned to a group of coincident primitives. The primitives of the group with the highest visual priority are rendered first. At each pixel where they win the depth test, they also store the group's stencil value in the stencil buffer. When subsequent primitives of the group with lower visual priority are rendered, they test the stencil buffer as well as the depth buffer. If the stencil value matches, meaning the pixel was previously claimed by a higher priority primitive of the group, the incoming lower priority primitive is discarded. If the stencil value does not match, then the simple depth test alone is used.
While this technique is useful, it relies on the primitives being rendered in a fixed order to correctly resolve the visual priority. There are also restrictions relative to the management of the stencil buffer such that multiple different coincident groups within the scene do not conflict.
In addition, most of these coincident primitive extensions are not completely compatible with advanced depth reduction techniques in use. For instance, the techniques may require rendering the primitives in a back-to-front order. Others require all of the pixels of all of the primitives to be rendered. This incompatibility reduces or eliminates the benefits associated with these advanced techniques when coincident primitives are rendered.
What is needed is a system and method for assisting the depth buffer to correctly select which primitive is closer to the view point without overly complicating the algorithm. What is also needed is a system and method for assisting the depth buffer to correctly select which primitive is closer to the view point with greater consistency. What is further needed is a system and method for assisting the depth buffer to correctly select which primitive is closer to the view point while allowing primitives to be rendered in any order. What is further needed is a system and method for assisting the depth buffer to correctly select which primitive is closer to the view point without imposing modeling restrictions or forcing unique requirements on the rendering process for coincident primitives.